package com.zzy.furns.domain;


import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 设计Session（内存）模式的购物车，使MVC设计理念中最原始的Model的表现形式
 */
public class Cart {

    private Map<Integer, CartItem> items = new HashMap<>();

    /**
     * totalCount为Integer类型，属于引用数据类型，与int基本数据类型不同，需要赋予初值才能进行 += 复合运算
     */
//    private Integer totalCount;

    /**
     * 添加家具到购物车
     */
    public void addItem(CartItem cartItem) {

        //原因：源码中多采用这种处理手段，个人认为是将数据与数据的处理相分离，防止处理过程影响数据（引用类型）
        CartItem addCartItemObj = cartItem;

        //遍历Cart，查看是否已经有CartItem
        int cartItemSize = items.size();
        if (cartItemSize == 0) {
            //Cart为空，没存储CartItem，可直接加入，索引为cartItem的id属性值
            items.put(addCartItemObj.getId(), addCartItemObj);
            return;
        }


//        items.forEach((index,old) -> {
//            //如果新增的CartItem存在，则不添加新的CartItem，只让存在的对应CartItem的count属性加一
//            if (index == addCartItemObj.getId()){
//                Integer oldCount = old.getCount();
//                old.setCount(oldCount + 1);
//                //注意：Lambda 中的 return 只退出当前迭代，不会终止整个方法
//                return;
//            }
//        });
        if (items.containsKey(addCartItemObj.getId())) {
            //新增的CartItem存在，不添加新的CartItem
            //取出存在的对应CartItem
            CartItem oldCartItem = items.get(addCartItemObj.getId());
            //count属性+1
            Integer oldCartItemCount = oldCartItem.getCount();
            oldCartItem.setCount(oldCartItemCount + 1);
            //totalPrice + price
            oldCartItem.setTotalPrice(oldCartItem.getTotalPrice().add(oldCartItem.getPrice()));
        } else {
            //新增的CartItem不存在，添加新的CartItem
            items.put(addCartItemObj.getId(), addCartItemObj);
        }
    }

    /**
     * 获取Cart中全部商品数量
     */
    public Integer getTotalCount(){
        //totalCount为Integer类型，属于引用数据类型，与int基本数据类型不同，需要赋予初值才能进行 += 复合运算
        //必须每次计算之前都将totalCount清零，否则totalCount数值会停留在上次Cart中全部商品数量
        Integer totalCount = 0;

//        items.forEach((index,cartItem) -> {
//            totalCount += cartItem.getCount();
//        });

        Set<Integer> keys = items.keySet();
        for (Integer id : keys) {
            totalCount += items.get(id).getCount();
        }

        return totalCount;
    }

    /**
     * 获取Cart中全部商品总价
     */
    public BigDecimal getTotalPrice(){
        BigDecimal totalCount = new BigDecimal(0);

        Set<Integer> keys = items.keySet();

        for (Integer key : keys) {
            totalCount = totalCount.add(items.get(key).getTotalPrice());
        }

        return totalCount;
    }

    /**
     * 修改购物车商品数量
     */
    public Long updateCount(Integer id, Integer newCount, Long stock){
        //根据id取出对应的CartItem对象
        CartItem cartItem = items.get(id);

//        if (cartItem == null){
//            //为了防止有人绕过前端，直接访问后端并输入一个前端购物车没有的商品id
//            //因为后续要删除数据库商品，可能造成数据的不一致
//            throw new ObjectNotFount("购物车中不存在id= " + id + " 的商品");
//        }

        //当然cartItem为空时也会抛出异常，所以可以在CartServlet调用该方法时进行捕获也可以
        //判断该CartItem对象的count与newCount大小，以明确是增加还是减少
        Integer oldCount = cartItem.getCount();

        if (oldCount == newCount){
            //当商品数量为1时，此时前端再减少发送过来的数量依然还是1，不需要更改，直接返回即可
            return stock;
        } else if (oldCount < newCount) {
            //增加商品数量，此时就需要考虑到库存的事情了
            if (stock > 0){
                //有库存
                cartItem.setCount(newCount);
//                cartItem.setTotalPrice(cartItem.getPrice().multiply(new BigDecimal(newCount)));
                cartItem.setTotalPrice(cartItem.getTotalPrice().add(cartItem.getPrice()));
                //根据前端逻辑，每次只会增加一件
                return stock - 1;
            } else {
                //没有库存
                System.out.println("没有库存");
                return stock;
            }
        } else {
            //减少商品数量，此时也需要考虑到库存的事情了
            cartItem.setCount(newCount);
            cartItem.setTotalPrice(cartItem.getPrice().multiply(new BigDecimal(newCount)));
            return stock + 1;
        }
    }

    /**
     * 删除购物车
     */
    public CartItem deleteItem(Integer id){
        //根据id移除items中对应的CartItem对象 此处不进行null判断，而是在CartServlet中调用该方法时通过try-catch捕获
        return items.remove(id);
    }

    /**
     * 清空购物车
     */
    public Map<Integer,Integer> clear(){
        HashMap<Integer, Integer> map = new HashMap<>();

        //遍历items，取出id与对应的商品数量count，并保存到map集合中
        items.forEach((id,cartItem) -> {
            map.put(id,cartItem.getCount());
        });

        //清空购物车
        items.clear();

        //返回id - count 的map集合，用于修改库存数据
        return map;
    }

    public Map<Integer, CartItem> getItems() {
        return items;
    }

    @Override
    public String toString() {
        return "Cart{" +
                "items=" + items +
                '}';
    }
}
